package com.zzh.util.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.zzh.util.excel.business.ExcelImportBusinessPrePo;
import com.zzh.util.excel.enums.ExportExcelClassEnumInterface;
import com.zzh.util.excel.handle.ExcelImportPostHandler;
import com.zzh.util.excel.handle.ExcelImportPreHandler;
import com.zzh.util.excel.registry.ExcelImportDateListRegistry;
import com.zzh.util.excel.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

@Slf4j
public class DataListener<T> implements ReadListener<T> {

    private static final int BATCH_COUNT = 100;
    private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    private ExportExcelClassEnumInterface exportExcelClassEnumInterface;
    private ExcelImportPreHandler preHandler;
    private ExcelImportPostHandler postHandler;
    private ExcelImportBusinessPrePo po;

    public DataListener(ExportExcelClassEnumInterface exportExcelClassEnumInterface,
                        ExcelImportBusinessPrePo po) {
        this.exportExcelClassEnumInterface = exportExcelClassEnumInterface;
        this.preHandler = exportExcelClassEnumInterface.getPreHandleClass();
        this.postHandler = exportExcelClassEnumInterface.getPostHandleClass();
        this.po = po;
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        log.info("");
        // 可添加表头处理逻辑
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
//        log.info("解析到一条数据:{}", JSON);
        cachedDataList.add(data);
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        log.info("所有数据解析完成！");
    }

    private Class<?> getBatchPoClass() {
        // 可以根据enum接口添加获取BatchPo类的方法
        // 或者通过命名约定等方式确定
        return exportExcelClassEnumInterface.getCreateBatchPoClass();
    }

    private Object createBatchPoInstance(List<?> dataList) {
        // 创建对应的BatchPo实例并设置数据
        // 这里需要根据具体业务实现
        return preHandler.preHandler(dataList,po);

    }

    private void saveData() {
        log.info("{}条数据，开始存储数据库！", cachedDataList.size());

        try {
            Class<?> serviceClass = exportExcelClassEnumInterface.getServiceClass();
            Object serviceInstance = SpringContextUtil.getBean(serviceClass);

            // 使用反射调用方法
            Method method = serviceClass.getMethod("createBatch", getBatchPoClass());
            Object batchPo = createBatchPoInstance(cachedDataList);
            method.invoke(serviceInstance, batchPo);
            if (po.getPostHandle()){
                postHandler.postHandler(ExcelImportDateListRegistry.getSuccessData(po.getUuid()));
            }

        } catch (Exception e) {
            log.error("调用service方法失败", e);
            throw new RuntimeException("保存数据失败", e);
        }

        log.info("存储数据库成功！");
    }
}